package com.hulk.service.impl;

/**
 * 封装ehCache常用方法
 * cacheManager：缓存管理器，以前是只允许单例的，不过现在也可以多实例了
 * cache：缓存管理器内可以放置若干cache，存放数据的实质，所有cache都实现了Ehcache接口
 * element：单条缓存数据的组成单位
 * @author CUIJIAJUN
 * @date   2016年11月18日
 * 
 */
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.stereotype.Service;

import com.hulk.common.StringUtil;
import com.hulk.service.EhCacheService;


@Service("ehCacheService")
public class EhCacheServiceImpl implements EhCacheService {

	private static final String JOIN = "_";

	@Resource
	private EhCacheCacheManager ehCacheCacheManager;
	
	private static CacheManager cacheManager;
	
	public synchronized CacheManager getInstance() {
		if (cacheManager == null) {
			cacheManager = ehCacheCacheManager.getCacheManager();
		}
		return cacheManager;
	}

	/**
	 * 设置缓存
	 * @param cacheName
	 * @param key
	 * @param value
	 */
	public void setObject(Object obj,String cacheName,String key,String... attachedKey) {
		Cache cache = getCache(cacheName);
		String okey = key;
		if(attachedKey!=null){
			for(String ak : attachedKey){
				if(!StringUtil.isNullStr(ak)){
					okey = okey + JOIN + ak;
				}
			}
		}
		Element element = new Element(okey, (Serializable)obj);
		cache.put(element);
	}

	/**
	 * 取得指定cacheName，key的缓存
	 * @param cacheName
	 * @param key
	 * @return
	 */
	public Object getObject(String cacheName, String key,String... attachedKey) {
		Cache cache = getInstance().getCache(cacheName);
		String okey = key;
		if(attachedKey!=null){
			for(String ak : attachedKey){
				if(!StringUtil.isNullStr(ak)){
					okey = okey + JOIN + ak;
				}
			}
		}
		Element element = cache.get(okey);
		return element == null ? null : element.getObjectValue();
	}

	/**
	 * 取得指定cacheName缓存
	 * @param cacheName
	 * @param key
	 * @return
	 */
	public Map<Object, Object> getObject(String cacheName) {
		Map<Object, Object> map = new HashMap<Object, Object>();
		Cache cache = getInstance().getCache(cacheName);
		Map<Object,Element> allObject = cache.getAll(cache.getKeys());
		for(Entry<Object, Element> entry:allObject.entrySet()){    
			map.put(entry.getKey(),entry.getValue());    
		}
		return map;
	}

	/**
	 * 取得全部缓存
	 * @param cacheName
	 * @param key
	 * @return
	 */
	public List<Map<Object, Object>> getAllObject() {
		List<Map<Object, Object>> result = new ArrayList<Map<Object,Object>>();
		String[] cacheNameStr = getInstance().getCacheNames();
		for(String cacheName : cacheNameStr){
			Map<Object, Object> map = new HashMap<Object, Object>();
			map.put(cacheName, this.getObject(cacheName));
			result.add(map);
		}
		return result;
	}


	/**
	 * 删除指定缓存
	 * @param cacheName
	 * @param key
	 */
	public void removeObjectByKey(String cacheName, String key,String... attachedKey) {
		String okey = key;
		if(attachedKey!=null){
			for(String ak : attachedKey){
				if(!StringUtil.isNullStr(ak)){
					okey = okey + JOIN + ak;
				}
			}
		}
		Cache cache = getInstance().getCache(cacheName);
		if(cache != null && cache.isKeyInCache(okey)){
			cache.remove(okey);
		}
	}

	/**
	 * 根据cacheName全部删除
	 * @param cacheName
	 */
	public void removeObjectByCacheName(String cacheName) {
		Cache cache = getInstance().getCache(cacheName);
		if(cache != null){
			cache.removeAll();	
		}
	}

	/**
	 * 删除内存中全部缓存
	 */
	public void removeAll() {
		String[] cacheNames = getInstance().getCacheNames();
		for(String cacheName : cacheNames){
			this.removeObjectByCacheName(cacheName);
		}
	}

	/**
	 * 获取Cache对象
	 * @param cacheName
	 * @return
	 */
	public Cache getCache(String cacheName) {
		Cache cache = getInstance().getCache(cacheName);
		if (cache == null) {
			throw new RuntimeException("根据cacheName=" + cacheName
					+ "无法获取到对于的cache!请检查配置文件");
		}
		return cache;
	}

	/**
	 * 获取指定Cache的全部key
	 * @param cacheName
	 * @return
	 */
	public List getKeys(String cacheName) {
		Cache cache = getInstance().getCache(cacheName);
		if (cache == null) {
			throw new RuntimeException("根据cacheName=" + cacheName
					+ "无法获取到对于的cache!请检查配置文件");
		}
		return cache.getKeys();
	}

	/**
	 * 缓存Cache是否包含某个key
	 * @param cacheName
	 * @param key
	 * @return
	 */
	public Boolean containsKey(String cacheName, String key) {
		if (this.getObject(cacheName, key) == null) {
			return false;
		} else {
			return true;
		}
	}
}